今天要進一步完成商店頁面,會用到 ViewComponent 來完成類別選單
ViewComponent 是 ASP.NET Core 新加入的網頁元件架構,檢視元件和部分檢視(PartialView)很像,都是用於在頁面上顯示可重複使用的內容,以減少程式碼。
在 ASP.NET 時期,如果要在 PartialView 顯示邏輯可以直接配合 Controller 的 Action ,雖然直觀但在執行上會完整執行整個生命週期,用太多會嚴重影響效能。於是就出現了檢視元件,能夠把邏輯也獨立出來處理,也可以把它當作一個小型的Controller來看。
幫大家整理一下重點:邏輯簡單用 PartialView ,邏輯複雜用 ViewComponent
檢視元件的用法是由類別( ViewComponent )和檢視( View )組成,和控制器長的差不多
但是預設路徑有所不同。如下圖所示,需要在專案底下新建資料夾ViewComponents,並且在/View/Shared/Components/[ViewComponents名稱]底下建立對應的視圖,路徑蠻複雜的要特別注意
在 /ViewComponents/CategoriesList.cs 建立 InvokeAsync() 動作
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using OnlineShop.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace OnlineShop.ViewComponents
{
    public class CategoriesList : ViewComponent
    {
        private readonly OnlineShopContext _context;
        public CategoriesList(OnlineShopContext context)
        {
            _context = context;
        }
        public async Task<IViewComponentResult> InvokeAsync()
        {
            var items = await _context.Category.ToListAsync();
            return View(items);
        }
    }
}
/View/Shared/Components/CategoriesList/Default.cshtml
和一般的 View 寫法一樣,把類別作為選單列出來
@model IEnumerable<OnlineShop.Models.Category>
<div>
    <div class="input-group mb-2">
        <input type="text" class="form-control" placeholder="Name" name="SearchString">
        <button class="btn btn-outline-secondary" type="submit" value="Search">
            <i class="fas fa-search"></i>
        </button>
    </div>
</div>
<div class="list-group">
    <a class="list-group-item list-group-item-action" asp-action="Index">所有商品</a>
    @foreach (var item in Model)
    {
        <a class="list-group-item list-group-item-action" 
            asp-action="Index" asp-route-cId="@item.Id">@item.Name</a>
    }
</div>  
接下來要從昨天建立好的商品列表把選單給加進來
在 Index.cshtml 上用 @await Component.InvokeAsync("CategoriesList") 調用檢視元件
<div class="row">
    <div class="col-3">
        <p></p>
        @await Component.InvokeAsync("CategoriesList")
    </div>
    <div class="col-9">
        <img src="~/image/banner.jpg" />
    </div>
</div>
最後看一下成果,就會發現類別選單被加入頁面了